home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / imlib / port / aix / gen_drv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-26  |  6.6 KB  |  301 lines

  1.  
  2. #define NUM_CHANNELS 8
  3. #define STDOUT_FD driver_out_fd
  4. #define STDIN_FD  driver_in_fd
  5.  
  6.  
  7.  
  8. #define DOUT_NAME  "/tmp/sfxdrv.signal"
  9. #define DIN_NAME "/tmp/sfxdrv.command"
  10.  
  11.  
  12. enum { SFXCMD_QUIT,
  13.        SFXCMD_REGISTER,
  14.        SFXCMD_UNREGISTER,
  15.        SFXCMD_PLAY
  16.      };
  17.  
  18. typedef struct sfx_handle_s sfx_handle;
  19.  
  20. struct sfx_handle_s
  21. {
  22.   int          handle; 
  23.   void         *shm_data_pointer;
  24.   sfx_handle   *next;  
  25.   long         size;
  26.   int          use_count;
  27. };
  28.  
  29. int driver_out_fd,driver_in_fd;
  30. sfx_handle *sfx_list=NULL;
  31. static int sfx_shm_id;
  32. static void *sfx_shm_addr;
  33.  
  34.  
  35. #define TOTAL_SIGS 29
  36.  
  37. int sigs[TOTAL_SIGS]={SIGHUP,SIGINT,SIGQUIT,SIGILL,SIGTRAP,
  38.               SIGABRT,SIGIOT,SIGBUS,SIGFPE,SIGKILL,
  39.               SIGUSR1,SIGSEGV,SIGUSR2,SIGPIPE,SIGALRM,
  40.               SIGTERM,SIGCHLD,SIGCONT,SIGSTOP,
  41.               SIGTSTP,SIGTTIN,SIGTTOU,SIGIO,
  42.               SIGURG,SIGXCPU,SIGXFSZ,SIGVTALRM,SIGPROF,
  43.               SIGWINCH};
  44.  
  45. struct channel
  46. {
  47.   unsigned char *data;         // next data to be qued
  48.   long left;                   // how much is left to play?  
  49.   unsigned char volume;        // indexed into volume table
  50.   unsigned long add_time;      // time at which the channel started playing
  51.   sfx_handle *snd;             // pointer to actual sound, so delete can stop us if need be
  52. } channels[NUM_CHANNELS];
  53.  
  54. #define uchar unsigned char
  55. short buf[BUF_SIZE];   // mixing buffer
  56.  
  57. // add a new sound effect into the channel list, if no free channel
  58. // oldest gets replaced with new sound
  59. void play(sfx_handle *snd, unsigned char volume)
  60. {
  61.   int i,free_channel=-1;
  62.   unsigned long oldest_channel=0,
  63.                 oldest_channel_time=10000,
  64.                 newest_channel_time=0;
  65.  
  66.   for (i=0;i<NUM_CHANNELS;i++)
  67.   {
  68.     if (channels[i].data)
  69.     { 
  70.       int my_time=channels[i].add_time;
  71.       if (my_time<oldest_channel_time)
  72.       {
  73.     oldest_channel=i;
  74.     oldest_channel_time=my_time;
  75.       }
  76.       if (my_time>newest_channel_time)
  77.     newest_channel_time=my_time;
  78.     } else free_channel=i;
  79.   }
  80.   
  81.   if (free_channel==-1)
  82.     free_channel=oldest_channel;
  83.  
  84.   channels[free_channel].snd=snd;
  85.   channels[free_channel].add_time=newest_channel_time+1;
  86.   channels[free_channel].data=(uchar *)snd->shm_data_pointer;
  87.   channels[free_channel].left=snd->size;
  88.   channels[free_channel].volume=volume*32/128;
  89. }
  90.  
  91.  
  92. int output_sounds()  // return 0 if no sounds to ouput
  93. {
  94.   unsigned char *s;
  95.   int i,j;
  96.   unsigned char *data;
  97.   
  98.   int run_size;
  99.   memset(buf,0,sizeof buf);
  100.   for (j=0;j<NUM_CHANNELS;j++)
  101.   {
  102.     data = channels[j].data;
  103.     if (data)
  104.     {
  105.       if (channels[j].left<=BUF_SIZE)    // handle imminent channel death
  106.       {
  107.         run_size=channels[j].left;
  108.         channels[j].data = NULL;
  109.       }
  110.       else
  111.       {
  112.         run_size=BUF_SIZE;
  113.         channels[j].data += BUF_SIZE;
  114.       }
  115.       channels[j].left -= BUF_SIZE;
  116.       
  117.       // add the chanels together into an int
  118.       // reserve the clip and scale to proper 16-bit for the output step
  119.       for (i=0;i<run_size;i++)
  120.         buf[i] += ((short)data[i] - 128) * channels[j].volume;
  121.  
  122.     }
  123.   }
  124.  
  125.   output_samples(buf);
  126.  
  127.   return 1;    // always say we have something, we will do blanks if nothing else
  128.  
  129. }
  130.  
  131.  
  132.  
  133. #ifdef __sgi
  134. void clean_up(...)
  135. #else
  136. void clean_up(int why)      // on exit unattach all shared memory links
  137. #endif
  138. {  
  139.   sfx_handle *last;
  140.   while (sfx_list)
  141.   {
  142.     last=sfx_list;
  143.     sfx_list=sfx_list->next;
  144.     free(last);
  145.   }
  146.   sound_uninit();
  147.   unlink(DIN_NAME);
  148.   unlink(DOUT_NAME);
  149.     shmdt(sfx_shm_addr);
  150. }
  151.  
  152. void die()
  153. { clean_up(0);
  154.   exit(0);
  155. }
  156.  
  157.  
  158. static int sound_fd_ready_to_read(int fd)
  159. {
  160.   struct timeval tv={0,0};
  161.   fd_set kbd_set,ex_set;
  162.   FD_ZERO(&kbd_set);
  163.   FD_SET(fd,&kbd_set);
  164.   memcpy((void *)&ex_set,(void *)&kbd_set,sizeof(ex_set));
  165.   select(FD_SETSIZE,&kbd_set,NULL,&ex_set,&tv);                // check for exception
  166.   if (FD_ISSET(fd,&ex_set))
  167.     die();
  168.   return (FD_ISSET(fd,&kbd_set));
  169. }
  170.  
  171.  
  172. void sound_watch()
  173. {
  174.  
  175.   sfx_handle *sfx;
  176.  
  177.   while (1)
  178.   {
  179.     while (sound_fd_ready_to_read(STDIN_FD))
  180.     {
  181.       uchar cmd;
  182.             int rc;
  183.       if ((rc=read(STDIN_FD,&cmd,1))!=1)
  184.       { die(); }
  185.       switch (cmd)
  186.       {
  187.     case SFXCMD_REGISTER :
  188.     {
  189.       int handle;
  190.       long size;
  191.       uchar return_code;
  192.       if (read(STDIN_FD,&handle,sizeof(handle))!=sizeof(handle))
  193.       { fprintf(stderr,"sndrv er1\n"); die(); }
  194.       if (read(STDIN_FD,&size,sizeof(size))!=sizeof(size))
  195.       { fprintf(stderr,"sndrv er2\n"); die(); }
  196.  
  197.       sfx=malloc(sizeof(sfx_handle));
  198.       sfx->handle=handle;
  199.       sfx->shm_data_pointer=sfx_shm_addr + handle;
  200.       sfx->size=size;
  201.       sfx->use_count=0;
  202.       sfx->next=sfx_list;
  203.       sfx_list=sfx;
  204.  
  205.       cmd=1;
  206.       if (write(STDOUT_FD,&cmd,sizeof(cmd))!=sizeof(cmd))
  207.       { fprintf(stderr,"sndrv er3\n"); die(); }
  208.  
  209.     } break;
  210.     case SFXCMD_PLAY :
  211.     {
  212.       int handle,i,volume;
  213.       sfx_handle *f;
  214.       if (read(STDIN_FD,&handle,sizeof(handle))!=sizeof(handle))
  215.         die();
  216.       if (read(STDIN_FD,&volume,sizeof(volume))!=sizeof(volume))
  217.         die();
  218.       for (f=sfx_list;f && f->handle!=handle;f=f->next);
  219.       if (f)
  220.         play(f,volume);
  221.       else fprintf(stderr,"sound driver : bad id to play\n");
  222.     } break;
  223.     default :     // die on unknown or DIE command
  224.     { die(); }
  225.       } 
  226.     }
  227.     output_sounds();
  228.   }
  229. }
  230.  
  231.  
  232. main()
  233. {
  234.  
  235.     int i;
  236.     uchar success;
  237. /*
  238.     int chd;
  239.   chd=fork();
  240.   if (chd)
  241.   {
  242.     printf("%d\n",chd);         // tell parent the sound driver's process number
  243.     return 0;
  244.   }
  245. */
  246.     printf("%d\n",getpid());         // tell parent the sound driver's process number
  247.     fclose(stdout);
  248.  
  249.   success=sound_init();    // initailize sound and send status to who ever ran us.
  250.   if (!success)
  251.   {
  252.     printf("-1");
  253.     return 0;
  254.   }
  255.  
  256.   unlink(DIN_NAME);
  257.   unlink(DOUT_NAME);
  258.  
  259. //  int old_mask=umask(S_IRWXU | S_IRWXG | S_IRWXO);
  260.   if (mkfifo(DIN_NAME,S_IRWXU | S_IRWXG | S_IRWXO))
  261.   { perror("Sound driver : unable to make fifo in /tmp");
  262.     return 0;
  263.   }
  264.   chmod(DIN_NAME,S_IRWXU | S_IRWXG | S_IRWXO);
  265.  
  266.   if (mkfifo(DOUT_NAME,S_IRWXU | S_IRWXG | S_IRWXO))
  267.   { perror("Sound driver : unable to make fifo in /tmp");
  268.     return 0;
  269.   }
  270.  
  271.   chmod(DOUT_NAME,S_IRWXU | S_IRWXG | S_IRWXO);
  272.   //umask(old_mask);
  273.  
  274.   driver_out_fd=open(DOUT_NAME,O_RDWR);
  275.   if (driver_out_fd<0)
  276.   { perror(DOUT_NAME); 
  277.     exit(1);
  278.   }
  279.  
  280.   driver_in_fd=open(DIN_NAME,O_RDWR);
  281.   if (driver_in_fd<0)
  282.   { perror(DIN_NAME); 
  283.     exit(1);
  284.   }
  285.  
  286.     if (read(STDIN_FD, &sfx_shm_id, sizeof(sfx_shm_id))!=sizeof(sfx_shm_id))
  287.         die();
  288.     sfx_shm_addr = shmat(sfx_shm_id, NULL, 0);
  289.     write(STDOUT_FD, (void*)&main, 1);
  290.  
  291.   for (i=0;i<TOTAL_SIGS;i++)
  292.     signal(sigs[i],clean_up);
  293.  
  294.   sound_watch();
  295.  
  296.   return 0;
  297. }
  298.  
  299.  
  300.  
  301.